﻿using Abide_AddOn_API.Interfaces;
using System;

namespace Abide_AddOn_API
{
    public class AddOnAPI : MarshalByRefObject
    {
        /// <summary>
        /// Represents the latest assembly version of Abide.
        /// This value is read-only.
        /// </summary>
        private static readonly Version AbideVersion = new Version(1, 13);

        private IAddOnHost host;
        private IAddOn client;

        /// <summary>
        /// Gets and returns the AddOn's Host
        /// </summary>
        public IAddOnHost Host
        {
            get { return host; }
        }
        /// <summary>
        /// Gets and returns the Client AddOn
        /// </summary>
        public IAddOn Client
        {
            get { return client; }
        }
        /// <summary>
        /// Gets and returns the Halo 2 Map
        /// </summary>
        public Abide_Halo_Library.Halo_2_Map.Halo2Map Halo2Map
        {
            get { return (Abide_Halo_Library.Halo_2_Map.Halo2Map)host.SendCommand(client, "GetHalo2Map"); }
        }
        /// <summary>
        /// Gets and returns the Halo 2 Beta Map
        /// </summary>
        public Abide_Halo_Library.Halo_2_Beta_Map.Halo2BetaMap Halo2BetaMap
        {
            get { return (Abide_Halo_Library.Halo_2_Beta_Map.Halo2BetaMap)host.SendCommand(client, "GetHalo2BetaMap"); }
        }
        /// <summary>
        /// Gets and returns the currently selected Halo 2 Index Entry
        /// </summary>
        public Abide_Halo_Library.Halo_2_Map.IndexEntry Halo2IndexEntry
        {
            get { return (Abide_Halo_Library.Halo_2_Map.IndexEntry)host.SendCommand(client, "GetHalo2IndexEntry"); }
        }
        /// <summary>
        /// Gets and returns the currently selected Halo 2 Beta Index Entry
        /// </summary>
        public Abide_Halo_Library.Halo_2_Beta_Map.IndexEntry Halo2BetaIndexEntry
        {
            get { return (Abide_Halo_Library.Halo_2_Beta_Map.IndexEntry)host.SendCommand(client, "GetHalo2BetaIndexEntry"); }
        }
        /// <summary>
        /// Gets and returns the Abide_AddOn_API.Meta.HaloPlugin associated with the selected Index Entry.
        /// </summary>
        public Meta.HaloPlugin SelectedPlugin
        {
            get { return (Meta.HaloPlugin)host.SendCommand(this, "GetPlugin"); }
        }
        /// <summary>
        /// Gets and returns the Debug Xbox
        /// </summary>
        public DebugXbox Xbox
        {
            get { return (DebugXbox)host.SendCommand(client, "GetXbox"); }
        }

        /// <summary>
        /// Returns an Abide_AddOn_API.Meta.HaloPlugin based on the the tagClass supplied.
        /// </summary>
        /// <param name="tagClass">The tag-type (or class) of the plugin you want to load.</param>
        /// <returns>An Abide_AddOn_API.Meta.HaloPlugin if successful, or null if unsuccessful.</returns>
        public Meta.HaloPlugin GetPlugin(string tagClass)
        {
            return (Meta.HaloPlugin)host.SendCommand(this, "GetPlugin", tagClass);
        }
        /// <summary>
        /// Sends the AddOn Host a command to reload the current Halo Map
        /// </summary>
        public void ReloadMap()
        {
            host.SendCommand(client, "ReloadMap");
        }
        /// <summary>
        /// Acts as a trigger for the IndexEntryChanged event
        /// </summary>
        public void ChangeIndexEntry()
        {
            //Trigger Client
            Client.OnIndexEntryChanged();
        }
        /// <summary>
        /// Acts as a trigger for the XboxChanged event
        /// </summary>
        public void ChangeXbox()
        {
            //Trigger Client
            Client.OnXboxChanged();
        }
        /// <summary>
        /// Initializes a new Abide_AddOn_API.AddOnAPI
        /// </summary>
        /// <param name="host">The AddOn's Host</param>
        /// <param name="client">The Client AddOn</param>
        public AddOnAPI(IAddOnHost host, IAddOn client)
        {
            this.host = host;
            this.client = client;
        }
        /// <summary>
        /// Retreives the latest assembly version of Abide.
        /// </summary>
        /// <returns>The latest version of the Abide assembly.</returns>
        internal static Version GetAbideVersion()
        {
            return new Version(AbideVersion.Major, AbideVersion.Minor);
        }
    }
}
